// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <ThresholdAttributes.h>
#include <DataNode.h>

// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Init utility for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void ThresholdAttributes::Init()
{

    ThresholdAttributes::SelectAll();
}

// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Copy utility for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void ThresholdAttributes::Copy(const ThresholdAttributes &obj)
{

    ThresholdAttributes::SelectAll();
}

// Type map format string
const char *ThresholdAttributes::TypeMapFormatString = THRESHOLDATTRIBUTES_TMFS;
const AttributeGroup::private_tmfs_t ThresholdAttributes::TmfsStruct = {THRESHOLDATTRIBUTES_TMFS};


// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Default constructor for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes::ThresholdAttributes() :
    ThresholdOpAttributes(ThresholdAttributes::TmfsStruct)
{
    ThresholdAttributes::Init();
}

// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Constructor for the derived classes of ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes::ThresholdAttributes(private_tmfs_t tmfs) :
    ThresholdOpAttributes(tmfs)
{
    ThresholdAttributes::Init();
}

// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Copy constructor for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes::ThresholdAttributes(const ThresholdAttributes &obj) :
    ThresholdOpAttributes(obj,ThresholdAttributes::TmfsStruct)
{
    ThresholdAttributes::Copy(obj);
}

// ****************************************************************************
// Method: ThresholdAttributes::ThresholdAttributes
//
// Purpose:
//   Copy constructor for derived classes of the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes::ThresholdAttributes(const ThresholdAttributes &obj, private_tmfs_t tmfs) :
    ThresholdOpAttributes(obj,tmfs)
{
    ThresholdAttributes::Copy(obj);
}

// ****************************************************************************
// Method: ThresholdAttributes::~ThresholdAttributes
//
// Purpose:
//   Destructor for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes::~ThresholdAttributes()
{
    // nothing here
}

// ****************************************************************************
// Method: ThresholdAttributes::operator =
//
// Purpose:
//   Assignment operator for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

ThresholdAttributes&
ThresholdAttributes::operator = (const ThresholdAttributes &obj)
{
    if (this == &obj) return *this;

    // call the base class' assignment operator first
    ThresholdOpAttributes::operator=(obj);

    ThresholdAttributes::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: ThresholdAttributes::operator ==
//
// Purpose:
//   Comparison operator == for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
ThresholdAttributes::operator == (const ThresholdAttributes &obj) const
{
    // Create the return value
    return (true);
}

// ****************************************************************************
// Method: ThresholdAttributes::operator !=
//
// Purpose:
//   Comparison operator != for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
ThresholdAttributes::operator != (const ThresholdAttributes &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: ThresholdAttributes::TypeName
//
// Purpose:
//   Type name method for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
ThresholdAttributes::TypeName() const
{
    return "ThresholdAttributes";
}

// ****************************************************************************
// Method: ThresholdAttributes::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   Tue Sep 13 08:54:28 PDT 2005
//
// Modifications:
//
//   Mark Blair, Tue Mar  7 13:25:00 PST 2006
//   Upgraded to support multiple threshold variables.
//
//   Mark Blair, Wed Sep 20 10:59:41 PDT 2006
//   Uses time ordinals from the Extents tool to avoid conflict with changes
//   hand-typed by the user in the Threshold operator's GUI window.
//
//   Mark Blair, Tue Oct  3 13:19:11 PDT 2006
//   Verifies that default plot variable is scalar if in threshold variable list.
//
//    Jeremy Meredith, Fri Feb 15 13:14:22 EST 2008
//    Added support for AxisRestrictionAttributes.
//
//   Jeremy Meredith, Tue Apr 22 14:31:20 EDT 2008
//   Removed Extents tool.  (Functionality subsumed by axis restriction tool.)
//
//   Kevin Griffin, Wed Feb 15 11:50:13 PDT 2017
//   Added boundsRange
//
// ****************************************************************************

bool
ThresholdAttributes::CopyAttributes(const AttributeGroup *atts)
{
    bool retval = false;

    if (TypeName() == atts->TypeName())
    {
        // Call assignment operator.
        const ThresholdAttributes *tmp = (const ThresholdAttributes *)atts;
        *this = *tmp;
        retval = true;
    }
    else if (atts->TypeName() == "AxisRestrictionAttributes")
    {
        const AxisRestrictionAttributes *arAtts =
            (const AxisRestrictionAttributes*)atts;

        stringVector toolVarNames = arAtts->GetNames();
        doubleVector toolMinima   = arAtts->GetMinima();
        doubleVector toolMaxima   = arAtts->GetMaxima();
        char buffer[50];

        for (size_t lv=0; lv < listedVarNames.size(); lv++)
        {
            for (size_t tv=0; tv < toolVarNames.size(); tv++)
            {
                if (toolVarNames[tv] == listedVarNames[lv])
                {
                    lowerBounds[lv] = toolMinima[tv];
                    upperBounds[lv] = toolMaxima[tv];
                    snprintf(buffer, sizeof(buffer), "%g:%g",toolMinima[tv],toolMaxima[tv]);
                    boundsRange[lv] =  std::string(buffer);
                }
                else if (toolVarNames[tv] == defaultVarName &&
                         listedVarNames[lv] == "default" &&
                         defaultVarIsScalar)
                {
                    lowerBounds[lv] = toolMinima[tv];
                    upperBounds[lv] = toolMaxima[tv];
                    snprintf(buffer, sizeof(buffer), "%g:%g",toolMinima[tv],toolMaxima[tv]);
                    boundsRange[lv] =  std::string(buffer);
                }
            }
        }

        retval = true;
    }

    return retval;
}

// ****************************************************************************
// Method: ThresholdAttributes::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
ThresholdAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new ThresholdAttributes(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: ThresholdAttributes::NewInstance
//
// Purpose:
//   NewInstance method for the ThresholdAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
ThresholdAttributes::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new ThresholdAttributes(*this);
    else
        retval = new ThresholdAttributes;

    return retval;
}

// ****************************************************************************
// Method: ThresholdAttributes::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
ThresholdAttributes::SelectAll()
{
    // call the base class' SelectAll() first
    ThresholdOpAttributes::SelectAll();
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: ThresholdAttributes::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Copied from ThresholdOpAttributes in common/state.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
//   Kevin Griffin, Wed Feb 15 11:50:13 PDT 2017
//   Added boundsRange
//
// ****************************************************************************

bool
ThresholdAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    ThresholdOpAttributes defaultObject;
    bool addToParent = false;
    // Create a node for ThresholdOpAttributes.
    DataNode *node = new DataNode("ThresholdAttributes");

    if(completeSave || !FieldsEqual(ID_outputMeshType, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("outputMeshType", outputMeshType));
    }

    if(completeSave || !FieldsEqual(ID_boundsInputType, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("boundsInputType", boundsInputType));
    }

    if(completeSave || !FieldsEqual(ID_listedVarNames, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("listedVarNames", listedVarNames));
    }

    if(completeSave || !FieldsEqual(ID_zonePortions, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("zonePortions", zonePortions));
    }

    if(completeSave || !FieldsEqual(ID_lowerBounds, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("lowerBounds", lowerBounds));
    }

    if(completeSave || !FieldsEqual(ID_upperBounds, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("upperBounds", upperBounds));
    }

    if(completeSave || !FieldsEqual(ID_boundsRange, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("boundsRange", boundsRange));
    }

    if(completeSave || !FieldsEqual(ID_defaultVarName, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("defaultVarName", defaultVarName));
    }

    if(completeSave || !FieldsEqual(ID_defaultVarIsScalar, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("defaultVarIsScalar", defaultVarIsScalar));
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}
// ****************************************************************************
// Method: ThresholdAttributes::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode representation of the object.
//
// Note:       Copied from ThresholdOpAttributes in common/state.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
ThresholdAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("ThresholdAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("outputMeshType")) != 0)
        SetOutputMeshType(node->AsInt());
    if((node = searchNode->GetNode("boundsInputType")) != 0)
        SetBoundsInputType(node->AsInt());
    if((node = searchNode->GetNode("listedVarNames")) != 0)
        SetListedVarNames(node->AsStringVector());
    if((node = searchNode->GetNode("zonePortions")) != 0)
        SetZonePortions(node->AsIntVector());
    if((node = searchNode->GetNode("lowerBounds")) != 0)
        SetLowerBounds(node->AsDoubleVector());
    if((node = searchNode->GetNode("upperBounds")) != 0)
        SetUpperBounds(node->AsDoubleVector());
    if((node = searchNode->GetNode("boundsRange")) != 0)
        SetBoundsRange(node->AsStringVector());
    if((node = searchNode->GetNode("defaultVarName")) != 0)
        SetDefaultVarName(node->AsString());
    if((node = searchNode->GetNode("defaultVarIsScalar")) != 0)
        SetDefaultVarIsScalar(node->AsBool());
}
///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: ThresholdAttributes::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
ThresholdAttributes::GetFieldName(int index) const
{
    return ThresholdOpAttributes::GetFieldName(index);
}

// ****************************************************************************
// Method: ThresholdAttributes::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
ThresholdAttributes::GetFieldType(int index) const
{
    return ThresholdOpAttributes::GetFieldType(index);
}

// ****************************************************************************
// Method: ThresholdAttributes::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
ThresholdAttributes::GetFieldTypeName(int index) const
{
    return ThresholdOpAttributes::GetFieldTypeName(index);
}

// ****************************************************************************
// Method: ThresholdAttributes::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
ThresholdAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    return ThresholdOpAttributes::FieldsEqual(index_, rhs);
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

